package com.lobov.entities.yale;

import java.io.Serializable;

import org.apache.hadoop.io.Text;

import com.lobov.entities.EntityIface;
import com.lobov.entities.Timer;
import com.lobov.utils.Generator;

/**
 * Лоскут матрицы (для йельского формата матриц) - несколько строк или столбцов матрицы в зависимости от
 * процессоров в кластере (количество строк и столбцов в лоскуте варьируется при
 * создании лоскута в зависимости о количества процессоров и размера матрицы)
 * 
 */
public class SnipYale extends Timer implements EntityIface, Serializable {

	private static final long serialVersionUID = 1L;
	private int orderNumInContainer;

	public SnipYale(SparseVector[] vectors, boolean compressed, int orderNumInContainer) {
		super();
		this.vectors = vectors;
		this.compressed = compressed;
		this.setOrderNumInContainer(orderNumInContainer);
	}
	
	public SnipYale(int xLength, int yLength, int orderNumInContainer){
		this.vectors = new SparseVector[yLength];
		for (int i = 0; i < yLength; i++) {
			vectors[i] = Generator.generateEmptyVector(xLength, i);
		}
		this.compressed = false;
		this.setOrderNumInContainer(orderNumInContainer);
	}
	
	private SparseVector[] vectors;
	private boolean compressed;
	private boolean flipped = false;

	public SparseVector[] getVectors() {
		return vectors;
	}

	public void setVectors(SparseVector[] vectors) {
		this.vectors = vectors;
	}

	public void setCompressed(boolean compressed) {
		this.compressed = compressed;
	}

	@Override
	public double getElementByXY(int x, int y) throws Exception {
		return vectors[y-1].getElementByX(x-1);
	}
	
	
	
	/**
	 * не используется в данном типе, всегда возвращает 0!!!
	 */
	@Override
	public double getElementByX(int x) throws Exception {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean isCompressed() {
		return compressed;
	}

	@Override
	public EntityIface compress() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public EntityIface deCompress() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public void addVector(SparseVector vector, int position) throws Exception {
		if (position > vectors.length - 1) {
			throw new Exception(
					"Вы пытаетесь вставить вектор за пределы матричного пространства, - позиция превышает "
							+ (vectors.length - 1));
		}
		vectors[position] = vector;
	}

	public boolean isFlipped() {
		return flipped;
	}

	public void setFlipped(boolean flipped) {
		this.flipped = flipped;
	}
	
	public int getXlength(){
		return vectors[0].getxLength();
	} 
	
	public int getYlength(){
		return vectors.length;
	}
	
	/**
	 * unused!!!
	 */
	@Override
	public void setElementByX(int x, double value) throws Exception {
		// TODO Auto-generated method stub
	}

	@Override
	public void setElementByXY(int x, int y, double value) throws Exception {
		vectors[y-1].setElementByX((x-1), value);
	} 
	
	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		for (int y = 0 ; y < getYlength(); y++){
			for(int x = 0; x < getXlength(); x++){
				try {
					sb.append(vectors[y].getElementByX(x));
				} catch (Exception e) {
					e.printStackTrace();
				}
				sb.append(" ");
			}
			sb.append("\n");
		}
		return sb.toString();
	}

	public int getOrderNumInContainer() {
		return orderNumInContainer;
	}

	public void setOrderNumInContainer(int orderNumInContainer) {
		this.orderNumInContainer = orderNumInContainer;
	}
	
	public int countVectors() {
		return vectors.length;
	}
	
	public Text toText() {
		Text text = null;
		StringBuilder sb = new StringBuilder();
		sb.append(orderNumInContainer+"@@@");
		for (int y = 0; y < getYlength(); y++) {
			for (int x = 0; x < getXlength(); x++) {
				try {
					sb.append(vectors[y].getElementByX(x));
				} catch (Exception e) {
					e.printStackTrace();
				}
				sb.append(" ");
			}
			sb.append("#");
		}
		
		text = new Text(sb.toString());
		return text;
	}
}
